<template>
    <tnxel-submit-form ref="form" :model="model" :rules="rules">
        <el-form-item label="作为命令模型属性">
            <el-switch v-model="enabled"/>
            <el-tooltip content="命令模型是添加和修改实体时提交的表单数据集，不包含实体主键属性" placement="top">
                <tnxel-icon class="text-secondary ms-3" value="QuestionFilled"/>
            </el-tooltip>
        </el-form-item>
        <template v-if="enabled">
            <el-form-item label="定义名称" prop="name" class="new-error-line">
                <tnxel-select v-model="nameDefault"
                    :items="defaultNameItems"
                    selector="radio"
                >
                    <template #option="{item}">
                        <span class="me-1">{{ item.text }}</span>
                        <span class="text-placeholder" v-if="item.value">({{ defaultName }})</span>
                    </template>
                </tnxel-select>
                <el-input ref="name"
                    v-model="model.name"
                    v-if="!nameDefault"/>
                <div class="form-item-tip">命令模型代码中的属性名</div>
            </el-form-item>
            <el-form-item label="字段类型" prop="typeId" class="new-error-line">
                <tnxel-select class="me-2"
                    v-model="typeIdDefault"
                    :items="defaultTypeIdItems"
                    selector="radio"
                >
                    <template #option="{item}">
                        <div class="flex-v-center">
                            <div class="me-1">{{ item.text }}</div>
                            <div class="flex-v-center text-placeholder" v-if="item.value">
                                <div>(</div>
                                <div :title="defaultType.getName()">{{ defaultType.simpleName }}</div>
                                <GenericTypeSpecify v-model="row.genericTypes"
                                    :app="app"
                                    :logic-type="row.typeId"
                                    :updatable="false"
                                />
                                <div v-if="row.arrayed">[]</div>
                                <div>)</div>
                            </div>
                        </div>
                    </template>
                </tnxel-select>
                <div class="flex-v-center flex-wrap" v-if="!typeIdDefault">
                    <LogicTypeSelect v-model="model.typeId" :app="app" :kind="clazz.kind"/>
                    <GenericTypeSpecify v-model="model.genericTypes" :app="app" :logic-type="model.typeId"/>
                    <ArrayedSelect v-model="model.arrayed"
                        class="ms-2"
                        :property="row"
                        show-if-updatable
                        title="是否数组"
                    />
                </div>
                <div class="form-item-tip">命令模型代码中的属性类型</div>
            </el-form-item>
            <el-form-item label="显示名称" prop="caption" class="new-error-line">
                <tnxel-select v-model="captionDefault"
                    :items="defaultCaptionItems"
                    selector="radio"
                >
                    <template #option="{item}">
                        <span class="me-1">{{ item.text }}</span>
                        <span class="text-placeholder" v-if="item.value">({{ this.row.caption }})</span>
                    </template>
                </tnxel-select>
                <el-input ref="caption"
                    v-model="model.caption"
                    v-if="!captionDefault"/>
                <div class="form-item-tip">显示在添加和修改界面表单中的名称</div>
            </el-form-item>
        </template>
    </tnxel-submit-form>
</template>

<script>
import ModelingApp from '@/logic/modeling/entity/ModelingApp.js';
import EntityClass from '@/logic/modeling/entity/EntityClass.js';

import LogicTypeSelect from './components/LogicTypeSelect.vue';
import GenericTypeSpecify from './components/GenericTypeSpecify.vue';
import ArrayedSelect from './components/ArrayedSelect.vue';

export default {
    components: {LogicTypeSelect, GenericTypeSpecify, ArrayedSelect,},
    props: {
        app: {
            type: ModelingApp,
            required: true,
        },
        clazz: {
            type: EntityClass,
            required: true,
        },
        row: {
            type: Object,
            required: true,
        },
        after: Function,
    },
    data() {
        let command = this.row.mappingCommand;
        let genericTypes = null;
        if (command?.genericTypes) {
            genericTypes = command.genericTypes.map(genericType => genericType.clone());
        }
        return {
            enabled: !!command,
            nameDefault: !command || !command.name,
            typeIdDefault: !command || !command.typeId,
            arrayedDefault: !command || !command.arrayed,
            captionDefault: !command || !command.caption,
            model: {
                id: command?.id || '',
                name: command?.name || '',
                typeId: command?.typeId || '',
                genericTypes: genericTypes,
                arrayed: typeof command?.arrayed === 'boolean' ? command.arrayed : null,
                caption: command?.caption || '',
            },
        };
    },
    computed: {
        defaultName() {
            let name = this.row.name;
            let type = this.app.findClass(this.row.typeId, true, true);
            if (type && type.kind.supports('association')) {
                let primaryPropertyName = this.app.getPrimaryLogicNames(type)[0];
                name += primaryPropertyName.firstToUpperCase();
            }
            if (this.row.parentPropertyName) {
                name = this.row.parentPropertyName + name.firstToUpperCase();
            }
            return name;
        },
        defaultType() {
            let type = this.app.findClass(this.row.typeId, true, true);
            if (type && type.kind.supports('association')) {
                let primaryLogicTypeId = this.app.getPrimaryLogicTypeIds(type)[0];
                return this.app.findClass(primaryLogicTypeId, true, true);
            }
            return type;
        },
        defaultNameItems() {
            return [{
                value: true,
                text: '默认',
            }, {
                value: false,
                text: '自定义',
            }];
        },
        defaultTypeIdItems() {
            return [{
                value: true,
                text: '默认',
            }, {
                value: false,
                text: '自定义',
            }];
        },
        defaultCaptionItems() {
            return [{
                value: true,
                text: '默认',
            }, {
                value: false,
                text: '自定义',
            }];
        },
        rules() {
            let rules = {};
            if (this.enabled) {
                if (!this.nameDefault) {
                    rules.name = [tnx.app.validator.requiredRule, tnx.app.validator.symbolRule];
                }
                if (!this.typeIdDefault) {
                    rules.typeId = [tnx.app.validator.requiredRule];
                }
                if (!this.captionDefault) {
                    rules.caption = [tnx.app.validator.requiredRule, tnx.app.validator.manualInputRule];
                }
            }
            return rules;
        },
    },
    watch: {
        nameDefault() {
            if (this.nameDefault) {
                this.model.name = '';
                this.$refs.form.clearValidate();
            } else {
                this.model.name = this.defaultName;
                this.$nextTick(() => {
                    this.$refs.name.select();
                });
            }
        },
        typeIdDefault() {
            if (this.typeIdDefault) {
                this.model.typeId = '';
                this.model.genericTypes = null;
                this.model.arrayed = null;
            } else {
                this.model.typeId = this.defaultType.id;
                this.model.genericTypes = this.row.genericTypes.map(genericType => genericType.clone());
                this.model.arrayed = this.row.arrayed;
            }
        },
        captionDefault() {
            if (this.captionDefault) {
                this.model.caption = '';
            } else {
                this.model.caption = this.row.caption;
                this.$nextTick(() => {
                    this.$refs.caption.select();
                });
            }
        },
    },
    methods: {
        dialog() {
            return {
                title: '命令模型属性设置',
                width: 500,
                type: 'confirm',
                click: this.toSubmit,
            }
        },
        toSubmit(yes, close) {
            if (yes) {
                this.$refs.form.toSubmit(() => {
                    let command = null;
                    if (this.enabled) {
                        command = Object.assign({}, this.model);
                    }
                    this.after(command);
                    close();
                });
                return false;
            }
        },
    }
}
</script>

<style lang="scss" scoped>
:deep(.logic-type-select-container) {
    width: fit-content;

    .el-cascader {
        width: 120px;
    }
}

:deep(.generic-type-specify) {
    width: fit-content;
}
</style>
